package com.promise.jokerdream.work.knight.dream

import com.promise.jokerdream.work.BaseWork
import com.promise.jokerdream.work.WorkResult
import com.promise.jokerdream.manager.ExecutionHistoryManager
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.database.entity.KnightDreamGameConfigEntity
import com.promise.jokerdream.config.game.KnightDreamPriority
import com.promise.jokerdream.repository.GameApi
import com.promise.jokerdream.repository.PhoneGameApi
import com.promise.jokerdream.repository.foldWithApiException
import com.promise.jokerdream.response.pc.QueryKnightDreamResponse
import com.promise.jokerdream.response.phone.FightKnightDreamXmlResponse
import com.promise.jokerdream.response.phone.EventData
import com.promise.jokerdream.response.phone.EventType
import com.promise.jokerdream.model.knight.KnightDreamMapping
import com.promise.jokerdream.response.pc.FightKnightDreamResponse
import com.promise.jokerdream.model.knight.KnightDreamEventModel
import com.promise.jokerdream.response.pc.FightKnightDreamChoose

/**
 * 江湖长梦状态机状态枚举
 */
enum class KnightDreamState {
    CHECK_ONGOING_INSTANCE,    // 检查是否有副本正在进行中
    CHECK_MAX_DAYS,            // 检查天数是否达到最大
    HANDLE_ADVENTURE_CHOICE,   // 处理奇遇选择（choose=1）
    HANDLE_EVENT_CHOICE,       // 处理事件选择（choose=0）
    HANDLE_CHALLENGE_FAILED,  // 处理挑战失败的情况（win=1）
    CHECK_CHALLENGE_COUNT,     // 检查挑战次数
    START_NEXT_CHALLENGE,      // 开始下一次挑战
    ERROR,                     // 错误状态
    COMPLETED                  // 完成
}

/**
 * 江湖长梦状态机上下文
 */
data class KnightDreamContext(
    val response: QueryKnightDreamResponse,
    val copyId: Int,
    val fightResponse: FightKnightDreamResponse? = null,
    val xmlResponse: FightKnightDreamXmlResponse? = null,
    val currentChallengeCount: Int = 0, // 当前挑战次数
    val isOngoingInstance: Boolean = false // 是否是正在进行的副本
)

/**
 * 状态机结果
 */
data class KnightDreamStateResult(
    val nextState: KnightDreamState,
    val updatedContext: KnightDreamContext? = null,
    val message: String? = null  // 错误消息或状态信息
)

/**
 * 江湖长梦工作
 * 负责执行江湖长梦相关的任务
 */
class KnightDreamWork(
    uin: String,
    private val config: KnightDreamGameConfigEntity
) : BaseWork(uin) {
    
    override val name: String
        get() = "江湖长梦"

    override val priority: Int
        get() = 9
    
    private val gameApi by lazy { GameApi() }
    private val phoneGameApi by lazy { PhoneGameApi() }
    private val historyManager by lazy { ExecutionHistoryManager.getInstance(AppContext.get()) }
    
    override suspend fun executeWork(): WorkResult {
        return try {
            // 查询江湖长梦状态
            val queryResult = gameApi.queryKnightDream()
            queryResult.foldWithApiException(
                onSuccess = { response ->
                    // 初始化状态机上下文
                    val context = KnightDreamContext(
                        response = response,
                        copyId = getInitialCopyId(response),
                        isOngoingInstance = hasOngoingInstance(response)
                    )
                    
                    // 执行状态机
                    executeStateMachine(context)
                    WorkResult.Success
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    WorkResult.Failure(Exception(msg), msg)
                }
            )
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            WorkResult.Failure(e, e.message)
        }
    }
    
    /**
     * 检查是否有正在进行的副本
     */
    private fun hasOngoingInstance(response: QueryKnightDreamResponse): Boolean {
        return response.copyList.any { it.status == 2 } // 状态2为进行中
    }
    
    /**
     * 获取初始副本ID
     */
    private fun getInitialCopyId(response: QueryKnightDreamResponse): Int {
        // 检查是否有副本正在进行中
        val ongoingInstance = response.copyList.find { it.status == 2 } // 状态2为进行中
        return ongoingInstance?.id ?: config.selectedDungeonId
    }
    
    /**
     * 执行状态机
     */
    private suspend fun executeStateMachine(initialContext: KnightDreamContext) {
        var currentState = KnightDreamState.CHECK_ONGOING_INSTANCE
        var context = initialContext
        
        while (currentState != KnightDreamState.COMPLETED && currentState != KnightDreamState.ERROR) {
            val result = when (currentState) {
                KnightDreamState.CHECK_ONGOING_INSTANCE -> {
                    handleCheckOngoingInstance(context)
                }
                KnightDreamState.CHECK_MAX_DAYS -> {
                    handleCheckMaxDays(context)
                }
                KnightDreamState.HANDLE_ADVENTURE_CHOICE -> {
                    handleAdventureChoice(context)
                }
                KnightDreamState.HANDLE_EVENT_CHOICE -> {
                    handleEventChoice(context)
                }
                KnightDreamState.HANDLE_CHALLENGE_FAILED -> {
                    handleChallengeFailed(context)
                }
                KnightDreamState.CHECK_CHALLENGE_COUNT -> {
                    handleCheckChallengeCount(context)
                }
                KnightDreamState.START_NEXT_CHALLENGE -> {
                    handleStartNextChallenge(context)
                }
                else -> {
                    KnightDreamStateResult(KnightDreamState.ERROR)
                }
            }
            currentState = result.nextState
            if (result.updatedContext != null) {
                context = result.updatedContext
            }
        }
        
        // 处理最终状态
        when (currentState) {
            KnightDreamState.ERROR -> {
//                historyManager.addHistory(name, "状态错误，已退出工作处理流程")
            }
            KnightDreamState.COMPLETED -> {
                // 任务完成
            }
            else -> {
                // 其他状态不应该到达这里
            }
        }
    }
    
    /**
     * 状态1：检查是否有副本正在进行中
     */
    private suspend fun handleCheckOngoingInstance(context: KnightDreamContext): KnightDreamStateResult {
        return try {
            if (context.copyId <= 0) {
                // 没有可用的副本ID，返回错误状态
                return KnightDreamStateResult(KnightDreamState.ERROR)
            }
            
            // 开始副本
            val beginResult = gameApi.beginKnightDreamInstance(context.copyId)
            
            beginResult.foldWithApiException(
                onSuccess = { fightResponse ->
                    // 更新上下文，进入下一个状态
                    val updatedContext = context.copy(fightResponse = fightResponse)
                    return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS, updatedContext)
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    // 开始副本失败，返回错误状态
                    return KnightDreamStateResult(KnightDreamState.ERROR)
                }
            )
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            KnightDreamStateResult(KnightDreamState.ERROR)
        }
    }
    
    /**
     * 状态2：检查天数是否达到最大
     */
    private suspend fun handleCheckMaxDays(context: KnightDreamContext): KnightDreamStateResult {
        val fightResponse = context.fightResponse ?: return KnightDreamStateResult(KnightDreamState.COMPLETED)
        
        if (fightResponse.curDays > fightResponse.maxDays) {
            // 副本完成，领奖并退出挑战
            val endResult = gameApi.endKnightDreamInstance()
            endResult.foldWithApiException(
                onSuccess = { response ->
                    historyManager.addHistory(name, response.getDescription())
                    return KnightDreamStateResult(KnightDreamState.CHECK_CHALLENGE_COUNT)
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    return KnightDreamStateResult(KnightDreamState.ERROR)
                }
            )
        }
        
        // 根据fightResponse的状态决定下一个状态
        return when {
            fightResponse.win == 1 -> KnightDreamStateResult(KnightDreamState.HANDLE_CHALLENGE_FAILED)  // win=1表示挑战失败
            fightResponse.choose == 1 -> KnightDreamStateResult(KnightDreamState.HANDLE_ADVENTURE_CHOICE)
            fightResponse.choose == 0 -> KnightDreamStateResult(KnightDreamState.HANDLE_EVENT_CHOICE)
            else -> KnightDreamStateResult(KnightDreamState.COMPLETED)
        }
    }
    
    /**
     * 状态3：处理奇遇选择（choose=1）
     */
    private suspend fun handleAdventureChoice(context: KnightDreamContext): KnightDreamStateResult {
        val fightResponse = context.fightResponse ?: return KnightDreamStateResult(KnightDreamState.COMPLETED)

        if (fightResponse.win == 1) {
            return KnightDreamStateResult(KnightDreamState.HANDLE_CHALLENGE_FAILED)
        } else {
            if (fightResponse.eventChoose.isNotEmpty()) {
                // choose=1时，需要选择奇遇，直接从eventChoose里选择
                val actionModel = KnightDreamMapping.getKnightDreamDayActionModel(
                    fightResponse.copyId,
                    fightResponse.curDays,
                    true // isAdventure
                )

                if (actionModel != null) {
                    val adventureId = getAdventureIndex(actionModel.actionList, fightResponse.eventChoose)
                    // 选择奇遇
                    val adventureResult = gameApi.chooseKnightDreamAdventure(adventureId)
                    adventureResult.foldWithApiException(
                        onSuccess = { fightResponse ->
//                            historyManager.addHistory(name, fightResponse.getDescription())
                            // 选择奇遇成功后，直接使用返回的fightResponse更新状态
                            val updatedContext = context.copy(fightResponse = fightResponse)
                            return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS, updatedContext)
                        },
                        onFailure = { code, msg ->
                            historyManager.addHistory(name, msg, code)
                            return KnightDreamStateResult(KnightDreamState.ERROR)
                        }
                    )
                }

                // 选择完奇遇后，重新查询状态来判断下一步
                return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS)
            } else {
                // eventChoose为空，进入下一天
                val nextDayResult = gameApi.goKnightDreamGoNextDay()
                nextDayResult.foldWithApiException(
                    onSuccess = { response ->
                        val updatedContext = context.copy(fightResponse = response)
                        return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS, updatedContext)
                    },
                    onFailure = { code, msg ->
                        historyManager.addHistory(name, msg, code)
                        return KnightDreamStateResult(KnightDreamState.ERROR)
                    }
                )
            }
        }
    }
    
    /**
     * 状态4：处理事件选择（choose=0）
     */
    private suspend fun handleEventChoice(context: KnightDreamContext): KnightDreamStateResult {
        val fightResponse = context.fightResponse ?: return KnightDreamStateResult(KnightDreamState.COMPLETED)
        
        if (fightResponse.eventList.isNotEmpty()) {
            // choose=0时，需要选择事件
            val xmlResult = phoneGameApi.queryKnightDreamXmlData(context.copyId)
            xmlResult.foldWithApiException(
                onSuccess = { xmlResponse ->
                    // 根据fightResponse.eventList选择事件
                    val selectedEvent = selectEventFromEventList(fightResponse.eventList)
                    if (selectedEvent != null) {
                        // 从mapping中获取actionModel
                        val isAdventure = selectedEvent.type == 1 // 1为奇遇
                        val actionModel = KnightDreamMapping.getKnightDreamDayActionModel(
                            fightResponse.copyId, 
                            fightResponse.curDays, 
                            isAdventure
                        )

                        val targetEvent = findEventFromXmlData(
                            xmlResponse.events,
                            actionModel?.level ?: 1,
                            actionModel?.index ?: 0,
                            selectedEvent.type
                        )

                        if (targetEvent != null) {
                            // 执行选择事件的操作
                            val chooseResult = gameApi.chooseKnightDreamEvent(targetEvent.eventId)
                            chooseResult.foldWithApiException(
                                onSuccess = { fightResponse ->
                                    if (fightResponse.getDescription().isNotEmpty()) {
                                        historyManager.addHistory(name, fightResponse.getDescription())
                                    }
                                    // 选择事件成功后，直接使用返回的fightResponse更新状态
                                    val updatedContext = context.copy(fightResponse = fightResponse)
                                    return KnightDreamStateResult(KnightDreamState.HANDLE_ADVENTURE_CHOICE, updatedContext)
                                },
                                onFailure = { code, msg ->
                                    historyManager.addHistory(name, msg, code)
                                    return KnightDreamStateResult(KnightDreamState.ERROR)
                                }
                            )
                        }
                    }
                },
                onFailure = { code, msg ->
                    if (msg == "很抱歉，系统繁忙，请稍后再试!") {
                        handleEventChoice(context)
                    } else {
                        historyManager.addHistory(name, msg, code)
                        // 查询XML数据失败，返回错误状态
                        return KnightDreamStateResult(KnightDreamState.ERROR)
                    }
                }
            )
            // 如果没有找到合适的事件，返回错误状态
            return KnightDreamStateResult(KnightDreamState.ERROR)
        } else {
            // eventList为空，进入下一天
            val nextDayResult = gameApi.goKnightDreamGoNextDay()
            nextDayResult.foldWithApiException(
                onSuccess = { response ->
                    val updatedContext = context.copy(fightResponse = response)
                    return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS, updatedContext)
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    return KnightDreamStateResult(KnightDreamState.ERROR)
                }
            )
        }
    }
    
    /**
     * 状态5：处理挑战失败的情况（win=1）
     */
    private suspend fun handleChallengeFailed(context: KnightDreamContext): KnightDreamStateResult {
        // win=1表示挑战失败，直接结束挑战
        val endResult = gameApi.endKnightDreamInstance()
        endResult.foldWithApiException(
            onSuccess = { response ->
                historyManager.addHistory(name, response.getDescription())
                return KnightDreamStateResult(KnightDreamState.CHECK_CHALLENGE_COUNT)
            },
            onFailure = { code, msg ->
                historyManager.addHistory(name, msg, code)
                // 结束副本失败，返回错误状态
                return KnightDreamStateResult(KnightDreamState.ERROR)
            }
        )
    }
    
    /**
     * 状态6：检查挑战次数
     */
    private suspend fun handleCheckChallengeCount(context: KnightDreamContext): KnightDreamStateResult {
        val currentCount = context.currentChallengeCount + 1
        
        // 如果当前是正在进行的副本，完成一次挑战
        if (context.isOngoingInstance) {
            // 正在进行的副本已完成，现在开始配置的副本
            if (config.selectedDungeonId > 0 && config.challengeCount > 0) {
                // 开始配置的副本挑战
                return KnightDreamStateResult(KnightDreamState.START_NEXT_CHALLENGE)
            } else {
                return KnightDreamStateResult(KnightDreamState.COMPLETED)
            }
        } else {
            // 当前是配置的副本
            if (currentCount < config.challengeCount) {
                // 还有更多挑战次数，继续下一次
                return KnightDreamStateResult(KnightDreamState.START_NEXT_CHALLENGE)
            } else {
                // 已达到配置的挑战次数，完成
                return KnightDreamStateResult(KnightDreamState.COMPLETED)
            }
        }
    }
    
    /**
     * 状态7：开始下一次挑战
     */
    private suspend fun handleStartNextChallenge(context: KnightDreamContext): KnightDreamStateResult {
        val nextCopyId = config.selectedDungeonId
        val nextCount = if (context.isOngoingInstance) {
            // 刚完成正在进行的副本，重置计数
            1
        } else {
            // 继续当前计数
            context.currentChallengeCount + 1
        }
        
        return try {
            // 开始副本
            val beginResult = gameApi.beginKnightDreamInstance(nextCopyId)
            
            beginResult.foldWithApiException(
                onSuccess = { fightResponse ->
                    // 更新上下文
                    val updatedContext = context.copy(
                        copyId = nextCopyId,
                        fightResponse = fightResponse,
                        currentChallengeCount = nextCount,
                        isOngoingInstance = false // 现在使用的是配置的副本
                    )
                    return KnightDreamStateResult(KnightDreamState.CHECK_MAX_DAYS, updatedContext)
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    // 开始下一次挑战失败，返回错误状态
                    return KnightDreamStateResult(KnightDreamState.ERROR)
                }
            )
            
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            KnightDreamStateResult(KnightDreamState.ERROR)
        }
    }
    
    /**
     * 根据actionList与eventChoose比较获取奇遇的index
     * @param actionList 动作列表
     * @param eventChoose 奇遇选择列表
     * @return 对应的index（从1开始），如果找不到返回1
     */
    private fun getAdventureIndex(actionList: List<String>, eventChoose: List<FightKnightDreamChoose>): Int {
        if (actionList.isEmpty() || eventChoose.isEmpty()) {
            return 1
        }
        
        // 遍历eventChoose，找到在actionList中匹配的第一个动作
        eventChoose.forEachIndexed { index, action ->
            if (actionList.contains(action.desc)) {
                return index + 1 // 返回从1开始的index
            }
        }
        
        // 如果没有找到匹配的，返回1
        return 1
    }
    
    /**
     * 根据配置优先级从eventList选择事件
     * @param eventList 事件列表
     * @return 选中的事件
     */
    private fun selectEventFromEventList(eventList: List<KnightDreamEventModel>): KnightDreamEventModel? {
        if (eventList.isEmpty()) return null
        
        // 根据配置的优先级选择事件
        val priority = try {
            KnightDreamPriority.valueOf(config.priority)
        } catch (e: Exception) {
            KnightDreamPriority.ADVENTURE // 默认值
        }
        return when (priority) {
            KnightDreamPriority.ADVENTURE -> {
                // 奇遇优先，选择奇遇事件
                eventList.find { it.type == 1 } // 1为奇遇
                    ?: eventList.find { it.type == 3 } // 3为战斗
                    ?: eventList.first() // 如果都没有，选择第一个
            }
            KnightDreamPriority.BATTLE -> {
                // 战斗优先，选择战斗事件
                eventList.find { it.type == 3 } // 3为战斗
                    ?: eventList.find { it.type == 1 } // 1为奇遇
                    ?: eventList.first() // 如果都没有，选择第一个
            }
        }
    }
    
    /**
     * 根据level、index和事件类型从XML数据中找到对应的事件
     * @param events XML事件列表
     * @param level 事件等级
     * @param index 事件索引
     * @param eventType 事件类型（1为奇遇、2为商店、3为战斗）
     * @return 对应的事件对象，如果找不到返回null
     */
    private fun findEventFromXmlData(
        events: List<EventData>, 
        level: Int, 
        index: Int,
        eventType: Int
    ): EventData? {
        // 将int类型转换为EventType枚举
        val targetEventType = when (eventType) {
            1 -> EventType.ADVENTURE
            2 -> EventType.SHOP
            3 -> EventType.BATTLE
            else -> EventType.UNKNOWN
        }
        
        // 找到匹配level和事件类型的事件
        var matchingEvents = events.filter {
            it.level == level && it.eventType == targetEventType 
        }
        
        if (matchingEvents.isEmpty()) {
            matchingEvents = events.filter {
                it.eventType == targetEventType
            }
            return matchingEvents.firstOrNull()
        }
        
        // 优先取index位置的事件
        if (index < matchingEvents.size) {
            return matchingEvents[index]
        }
        
        // 如果index位置没有，则取第一个
        return matchingEvents.firstOrNull()
    }
}